package jfox.platform.common;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import jfox.platform.infrastructure.EntityObject;
import org.json.JSONObject;

/**
 * 对于异步请求，通过该对象返回数值，使用 json_response.vhtml 作为 targetView
 *
 * @author <a href="mailto:yang_y@sysnet.com.cn">Young Yang</a>
 */
public class JSONResponse {

    /**
     * 是否成功
     */
    private boolean success = true;
    
    /**
     * 携带的对象
     */
    private Object returnObject = null;

    /**
     * 是否有异常
     */
    private Exception exception = null;

    //TODO: 携带其它信息，比如：对于分页来讲，需要 totalCount;
    private Map<String, Object> attributes = new HashMap<String, Object>(2);

/*
    public JSONResponse() {
    }
*/

    private JSONResponse(boolean success, Object returnObject, Exception exception) {
        this.success = success;
        this.returnObject = returnObject;
        this.exception = exception;
    }

    /**
     * 创建一个成功的 JSONResponse
     * @param returnObject 需要返回给浏览器的对象，可以为 null
     */
    public static JSONResponse createSuccessJSONResponse(Object returnObject){
        return new JSONResponse(true, returnObject, null);
    }

    /**
     * 创建一个执行失败的 JSONResponse
     * 对于响应 AJAX 调用 的Action，在有异常发生时，都应该返回 Failure JSONResponse，以便前台弹出错误框
     *
     * 如果直接将异常抛出，将自动弹出 AJAX Failure MessageBox，打印异常堆栈
     * 
     * @param returnObject 返回的对象，可以为 null
     * @param exception 异常
     */
    public static JSONResponse createFailureJSONResponse(Object returnObject, Exception exception){
        return new JSONResponse(false, returnObject, exception);
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public Object getReturnObject() {
        return returnObject;
    }

    public void setReturnObject(Object returnObject) {
        this.returnObject = returnObject;
    }

    public Exception getException() {
        return exception;
    }

    public void setException(Exception exception) {
        this.exception = exception;
    }

    public JSONObject toJSONObject(){
        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("success", isSuccess());
            if(getReturnObject() instanceof EntityObject) {
                jsonObject.put("returnObject", JSONUtils.convertEntity((EntityObject)getReturnObject()));
            }
            else if(getReturnObject() instanceof Collection){
                //add by mozhijia 2007-10-28
                //返回一个列表的JSON对象
                jsonObject.put("returnObject", JSONUtils.convertEntities((Collection<? extends Object>)getReturnObject()));
            }
            else if(getReturnObject() instanceof PaginationList){
                //用来支持 extjs 分页
                jsonObject.put("returnObject", JSONUtils.convertEntities(((PaginationList)getReturnObject()).getDatas()));
                jsonObject.put("totalCount", ((PaginationList)getReturnObject()).getTotalCount());
            }
            else {
                jsonObject.put("returnObject", getReturnObject());
            }

            if(getException() != null) {
                jsonObject.put("exception", " Type:     " + getException().getClass().getName() + "\n Message: " + getException().getMessage());
            }
            else {
                jsonObject.put("exception", getException());
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return jsonObject;
    }

    public String toString() {
//        System.out.println(toJSONObject().toString());
        return toJSONObject().toString();
    }

    public static void main(String[] args) {

    }
}
